package com.wfm;

import com.wfm.jwt.JWTAccessDeniedHandler;
import com.wfm.jwt.JWTAuthenticationEntryPoint;
import com.wfm.jwt.JWTFilter;
import com.wfm.session.SessionAccessDeniedHandler;
import com.wfm.session.SessionAuthenticationEntryPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    @Order(0) // 最高优先级，这里处理的都是以 /api/** 开头的接口，使用 jwt 做认证
    public SecurityFilterChain jwtFilterChain(HttpSecurity http) throws Exception {

        // @formatter:off
        http.requestMatchers().antMatchers("/api/**").and()
            .authorizeRequests()
                .antMatchers("/api/login").permitAll()
                .antMatchers("/api/admin").hasRole("ADMIN")// /admin 接口需要 ADMIN 权限
                .anyRequest().authenticated();// 其他的所以接口都需要认证才可以访问

//  版本3的写法：
//        http.securityMatcher("/api/**").authorizeHttpRequests(authorize -> authorize
//                .requestMatchers("/api/login").permitAll() // /public 接口可以公开访问
//                .requestMatchers("/api/admin").hasAuthority("ADMIN") // /admin 接口需要 ADMIN 权限
//                .anyRequest().authenticated()); // 其他的所以接口都需要认证才可以访问
        // @formatter:on

        // 设置异常的EntryPoint的处理
        http.exceptionHandling(exceptions -> exceptions
                // 未登录
                .authenticationEntryPoint(new JWTAuthenticationEntryPoint())
                // 权限不足
                .accessDeniedHandler(new JWTAccessDeniedHandler()));

        // 关闭 csrf 保护
        http.csrf(csrf -> csrf.disable());

        // 在过滤器链中添加 JWTFilter
        http.addFilterBefore(new JWTFilter(), LogoutFilter.class);

        return http.build();
    }

    @Bean
    @Order(1) // 次高优先级，处理会话认证
    public SecurityFilterChain sessionFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http.authorizeRequests(authorize ->
                authorize.antMatchers("/public","/login").permitAll()// /public 接口可以公开访问
                        .antMatchers("/admin").hasAuthority("ADMIN")// /admin 接口需要 ADMIN 权限
                        .anyRequest().authenticated()// 其他的所以接口都需要认证才可以访问
        );
        // @formatter:on

        // 设置异常的EntryPoint的处理
        http.exceptionHandling(exceptions -> exceptions
                // 未登录
                .authenticationEntryPoint(new SessionAuthenticationEntryPoint())
                // 权限不足
                .accessDeniedHandler(new SessionAccessDeniedHandler()));

        return http.build();
    }


    @Bean
    public AuthenticationManager authenticationManager
            (AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    // 配置内存型账户密码
//    @Bean
//    public UserDetailsService users(){
//        UserDetails userDetails = User.withDefaultPasswordEncoder().username("wfm").password("wfm").roles("user").build();
//        return new InMemoryUserDetailsManager(userDetails);
//    }




}
